:- use_module('flog.pro').

:- op(100, xfx, '::').

A :: B := A :-
	B~>[A].

A * B := C :-
	A::number /\ B::number /\
	C is A * B.
A + B := C :-
	A::number /\ B::number /\
	C is A + B.
A - B := C :-
	A::number /\ B::number /\
	C is A - B.

fact(1) := 1.
fact(N) := ? N * fact(N - 1) :- N > 1.

fmap(_, []) := [].
fmap(F, [H|T]) := [? F~>[H] | ? fmap(F, T)].

.(X, T) := .(X, T).

F ~> L := ? FF :- FF =.. [F|L].

fold(F, I, [H|T]) := ? fold(F, F~>[I, H], T).
fold(_, I, []) := I.

:- op(512, xfx, '..').

A .. B := [A| ?A + 1 .. B] :- A < B.
A .. A := [A].

list(X) := list(X).

%:- public(list/2).
%:- public('::'/2).

Value :: Type :-
	Type~>[Value].

list(_, []).
list(Type, [H|T]) :-
	H::Type /\
	T::list(Type).

inc(X) := ? X + 1.

take(_, 0) := [].
take([H|T], N) := [H|?take(T, N - 1)] :- N > 0.

pred(1).